/*
 * Project: Hell Watch
 * Author: pajoke
 * Copyright: (C) 2014 Hell Prototypes
 * License: GNU GPL v3 (see License.txt)
 * Web: http://www.hellprototypes.com
 */

#include <avr/pgmspace.h>
#include <stdio.h>
#include "typedefs.h"
#include "apps/battery_log.h"
#include "devices/buttons.h"
#include "display.h"
#include "draw.h"
#include "menu.h"
#include "resources.h"
#include "devices/oled.h"
#include "millis/millis.h"
#include "watchconfig.h"
#include "watchface.h"
#include "animation.h"
#include "devices/battery.h"
#include "devices/accelerate.h"

static bool up(void);
static bool down(void);
static bool select(void);
static display_t draw(void);
static void read_battery_log(void);
static void draw_0V_line(void);
static void draw_Cursor_line(byte offset);

static byte battery_log[BAT_LOG_SIZE];
static byte current_cursor;
static uint16_t timeout;

void battery_log_open()
{
	menu_close();

	display_setDrawFunc(draw);
	buttons_setFunc(BTN_SELECT,	select);
	buttons_setFunc(BTN_DOWN,	down);
	buttons_setFunc(BTN_UP,		up);

	read_battery_log();
	current_cursor = BAT_LOG_SIZE - 1;
	timeout = 0;
}

static bool up()
{
	//read_battery_log();
	timeout = 0;
	if(current_cursor < BAT_LOG_SIZE-1) {
		current_cursor++;
	}
	return true;
}

static bool down()
{
	//read_battery_log();
	timeout = 0;
	if(current_cursor > 0) {
		current_cursor--;
	}
	return true;
}

static bool select()
{
	animation_start(watchface_loadFace, ANIM_MOVE_OFF);
	return true;
}

static display_t draw()
{
	byte offset;
	display_t ret = DISPLAY_BUSY;

	int16_t accel_x = accel_get_x();
	if(accel_x > 250) {
		timeout = 0;
		up();
	} else if(accel_x < -250) {
		down();
		timeout = 0;
	} else {
		if(timeout > 1000) {
			ret = DISPLAY_DONE;
		} else {
			timeout++;
		}
	}

	uint16_t vol = (uint16_t)battery_log[current_cursor] * 100 / 2;
	char buff[25];
	sprintf_P(buff, PSTR("%u HourAgo:%dmV"), BAT_LOG_SIZE - current_cursor, vol
								 );
	draw_string(buff, false, 0, 0);
	buff[0] = '0';
	buff[1] = '>';
	buff[2] = '\0';
	draw_string(buff, false, 0, 56);

	if(current_cursor > (BAT_LOG_SIZE - 64)) {
		offset = BAT_LOG_SIZE - 128;
		draw_Cursor_line(current_cursor - (BAT_LOG_SIZE - 128));
	} else if (current_cursor < 64) {
		offset = 0;
		draw_Cursor_line(current_cursor);
	} else {
		offset = current_cursor - 64;
		draw_Cursor_line(64);
	}
	draw_0V_line();

	byte y;
	for(byte i=0; i<128; i++) {
		y = battery_log[offset + i]/2;
		if(y > 63) {
			y = 63;
		}
		draw_one_Pixel(i, 63 - y);
	}

	return ret;
}

static void draw_0V_line(void)
{
	for(byte i=12; i<128; i+=4) {
		draw_one_Pixel(i, 59);
	}
}

static void draw_Cursor_line(byte offset)
{
	offset &= 0x7F;

	for(byte i=12; i<63; i+=4) {
		draw_one_Pixel(offset, i);
	}
}

static void read_battery_log(void)
{
	if(!battery_get_log(0, BAT_LOG_SIZE, battery_log)) {
		return;
	}
	byte index;
	for(index=0; index<BAT_LOG_SIZE; index++) {
		if(battery_log[index] & 0x80) {
			battery_log[index] &= 0x7F;
			break;
		}
	}

	if(index >= BAT_LOG_SIZE) {
		return;
	}
	index++;

	if(index >= BAT_LOG_SIZE) {
		index = 0;
	}
	if(!battery_get_log(index, BAT_LOG_SIZE-index, battery_log)) {
		return;
	}
	if(!battery_get_log(0, index, &battery_log[BAT_LOG_SIZE - index])) {
		return;
	}
	battery_log[BAT_LOG_SIZE-1] &= 0x7F;//last is the latest
}